package org.word.utils;

import org.springframework.util.CollectionUtils;
import org.word.model.definition.SwaggerModelDefinition;
import org.word.model.definition.SwaggerModelDefinitionRef;
import org.word.model.definition.SwaggerModelProperty;
import org.word.model.path.ParameterItem;

import java.util.*;

public class ModelDefinitionUtils {

    public static String getDefinitionNameFromRef(String ref) {
        return ref.substring(ref.lastIndexOf("/") + 1);
    }


    public static LinkedHashMap<String, SwaggerModelProperty> getSwaggerModelPropertyMap(LinkedHashMap<String, SwaggerModelDefinition> swaggerModelDefinitions, String ref) {
        String definitionName = ModelDefinitionUtils.getDefinitionNameFromRef(ref);

        SwaggerModelDefinition swaggerModelDefinition = swaggerModelDefinitions.get(definitionName);
        if (swaggerModelDefinition == null) {
            throw new RuntimeException();
        }

        return swaggerModelDefinition.getProperties();
    }

    /**
     * 查看当前这个属性，是否是ref引用；如果是的话，要获取其下的属性列表
     * 涉及递归处理
     * @param visitedDefinitionSet
     * @param swaggerModelProperty
     * @param modelDefinitionLinkedHashMap
     * @return  swaggerModelProperty属性为ref的话，获取其属性列表
     */
    public static List<SwaggerModelProperty> getChildPropertiesOfProperty(HashSet<String> visitedDefinitionSet, SwaggerModelProperty swaggerModelProperty,
                                                                          LinkedHashMap<String, SwaggerModelDefinition> modelDefinitionLinkedHashMap) {


        String type = swaggerModelProperty.getType();
        int outerLevel = swaggerModelProperty.getLevel();

        if ("array".equals(type)) {
            SwaggerModelDefinitionRef items = swaggerModelProperty.getItems();
            String ref = items.getRef();

            if (ref == null) {
                String itemsType = items.getType();

                SwaggerModelProperty property = new SwaggerModelProperty();
                property.setLevel(swaggerModelProperty.getLevel() + 1);
                property.setType(itemsType);

                ArrayList<SwaggerModelProperty> result = new ArrayList<>();
                result.add(property);

                return result;
            } else {
                return getSwaggerModelPropertiesByModelName(visitedDefinitionSet,modelDefinitionLinkedHashMap, outerLevel, ref);
            }

        } else if (!org.springframework.util.StringUtils.isEmpty(swaggerModelProperty.getRef())) {
            String ref = swaggerModelProperty.getRef();

            return getSwaggerModelPropertiesByModelName(visitedDefinitionSet,modelDefinitionLinkedHashMap, outerLevel, ref);
        }

        return null;
    }


    /**
     * 从一个引用的model中，获取其属性列表；涉及递归处理
     *
     * @param visitedDefinitionSet
     * @param modelDefinitionLinkedHashMap
     * @param outterLevel
     * @param ref
     * @return
     */
    private static List<SwaggerModelProperty> getSwaggerModelPropertiesByModelName(HashSet<String> visitedDefinitionSet, LinkedHashMap<String, SwaggerModelDefinition> modelDefinitionLinkedHashMap, int outterLevel, String ref) {
        String definitionName = getDefinitionNameFromRef(ref);

        /**
         * 根据model名称，获取model的definition
         */
        SwaggerModelDefinition swaggerModelDefinition = modelDefinitionLinkedHashMap.get(definitionName);

        LinkedHashMap<String, SwaggerModelProperty> properties = swaggerModelDefinition.getProperties();
        Collection<SwaggerModelProperty> propertyCollection = properties.values();
        if (CollectionUtils.isEmpty(propertyCollection)) {
            return new ArrayList<>();
        }
        /**
         * 如果没访问过，加入已访问的集合；
         * 否则返回空列表
         */
        if (!visitedDefinitionSet.contains(definitionName)) {
            visitedDefinitionSet.add(definitionName);
        } else {
            return new ArrayList<>();
        }

        ArrayList<SwaggerModelProperty> result = new ArrayList<>();
        for (SwaggerModelProperty value : propertyCollection) {
            value.setLevel(outterLevel + 1);
            result.add(value);
            visitedDefinitionSet.add(value.getKey());

            /**
             * 这里递归了
             */
            List<SwaggerModelProperty> list = getChildPropertiesOfProperty(visitedDefinitionSet, value, modelDefinitionLinkedHashMap);
            if (CollectionUtils.isEmpty(list)) {
                continue;
            }
//                list.stream().forEach(item -> item.setLevel(value.getLevel() + 1));
            result.addAll(list);
        }
        return result;
    }



    public static void fillChildPropertiesOfCurrentProperty(ParameterItem parameterItem, ArrayList<ParameterItem> childParameterItemList, List<SwaggerModelProperty> childModelPropertiesList) {
        /**
         * 2:加入当前属性的子属性
         */
        {
            for (SwaggerModelProperty childModelProperty : childModelPropertiesList) {
                ParameterItem childParameterItem = new ParameterItem();
                childParameterItem.setLevel(childModelProperty.getLevel());
                childParameterItem.setName(childModelProperty.getKey());
                if (parameterItem != null) {
                    childParameterItem.setIn(parameterItem.getIn());
                }
                childParameterItem.setType(childModelProperty.getType());
                childParameterItem.setDescription(childModelProperty.getDescription());
                if (parameterItem != null) {
                    childParameterItem.setRequired(parameterItem.getRequired());
                } else {
                    childParameterItem.setRequired(true);
                }
                childParameterItem.setSchema(null);

                childParameterItemList.add(childParameterItem);
            }
        }
    }
}
